<template>
  <n-modal
    v-model:show="showModal"
    preset="dialog"
    title="编辑菜单"
    width="600px"
    negative-text="取消"
    positive-text="确认"
    @positive-click="handleConfirm"
    @negative-click="handleCancel"
  >
    <n-form
      :model="formData"
      label-placement="left"
      label-width="auto"
      ref="ruleForm"
      :rules="rules"
    >
      <n-form-item path="pid" label="上级菜单">
        <n-tree-select
          v-model:value="formData.pid"
          :options="parentTreeOptions"
          filterable
        />
      </n-form-item>
      <n-form-item path="title" label="菜单标题">
        <n-input v-model:value="formData.title"></n-input>
      </n-form-item>
      <n-form-item path="code" label="菜单编码">
        <n-input v-model:value="formData.code"></n-input>
      </n-form-item>
      <n-form-item path="icon" label="菜单图标">
        <n-input v-model:value="formData.icon"></n-input>
      </n-form-item>
      <n-form-item path="type" label="菜单类型">
        <n-select
          v-model:value="formData.type"
          :options="typeOptions"
        ></n-select>
      </n-form-item>
      <n-form-item path="url" label="菜单地址">
        <n-input v-model:value="formData.url"></n-input>
      </n-form-item>
      <n-form-item path="redirect" label="重定向地址">
        <n-input v-model:value="formData.redirect"></n-input>
      </n-form-item>
      <n-form-item path="api" label="权限接口">
        <n-input v-model:value="formData.api"></n-input>
      </n-form-item>
      <n-form-item path="enabled" label="状态">
        <n-switch v-model:value="formData.enabled"></n-switch>
      </n-form-item>
      <n-form-item path="hidden" label="隐藏">
        <n-switch v-model:value="formData.hidden"></n-switch>
      </n-form-item>
      <n-form-item path="keepalive" label="缓存">
        <n-switch v-model:value="formData.keepalive"></n-switch>
      </n-form-item>
      <n-form-item path="sort" label="排序">
        <n-input-number v-model:value="formData.sort"></n-input-number>
      </n-form-item>
    </n-form>
    <OptForm :model="formData" :options="formItems"></OptForm>
  </n-modal>
</template>
<script lang="ts" setup>
import { ref } from 'vue';
import {
  useSysMenuApi,
  type SysMenuRaw,
  type SysMenuItem,
} from '@/api/system/menu';
import type { FormInst, FormRules, TreeSelectOption } from 'naive-ui';
import { OptForm, type OptFormItemProps } from '@code4x/naive-components';
defineOptions({ name: 'MenuForm' });
const showModal = ref(false);
const ruleForm = ref<FormInst>();
const formData = ref<SysMenuRaw>({
  api: '',
  code: '',
  enabled: true,
  hidden: false,
  icon: '',
  keepalive: false,
  pid: '-1',
  position: 1,
  sort: 0,
  target: '_blank',
  title: '',
  type: 1,
  url: '',
  redirect: '',
});
const rules: FormRules = {
  title: [{ required: true, message: '标题为必填项', trigger: 'blur' }],
  code: [
    {
      required: true,
      message: '编码为必填项',
      trigger: 'blur',
    },
    {
      pattern: /^[A-Z][\w\d]+/,
      message: '编码必须以大写字母开头，且至少包含两个字符！',
      trigger: ['input', 'blur'],
    },
  ],
  icon: [{ required: true, message: '图标为必填项', trigger: 'blur' }],
  url: [{ required: true, message: '菜单地址为必填项', trigger: 'blur' }],
};

const typeOptions = [
  { label: '目录', value: 1 },
  { label: '页面', value: 2 },
  { label: '外链', value: 3 },
];

const formItems: OptFormItemProps[] = [
  {
    type: 'NInput',
    formItem: { label: '上级菜单', path: 'pid' },
  },
];

const parentTreeOptions = computed<TreeSelectOption[]>(() => {
  const topLevel: TreeSelectOption = {
    label: '顶级菜单',
    key: '-1',
    children: [],
  };
  const recursive = (tree: SysMenuItem[]): TreeSelectOption[] => {
    return tree.map((el) => {
      return {
        label: el.title,
        key: el.menuId,
        disabled: el.menuId === formData.value.menuId,
        isLeaf: !(Array.isArray(el.children) && el.children.length),
        children:
          Array.isArray(el.children) && el.children.length
            ? recursive(el.children)
            : [],
      };
    });
  };
  topLevel.children = recursive(originTree.value);

  return [topLevel];
});

const init = async (id: string, pid: boolean = false) => {
  if (id && pid) {
    formData.value.pid = id;
  }
  if (id && !pid) {
    try {
      const res = await useSysMenuApi.get(id);
      formData.value = res.data;
    } catch (error) {
      /**Empty */
    }
  }
  getTree();
  showModal.value = true;
};

const handleConfirm = async () => {
  try {
    const res = await ruleForm.value?.validate();
    console.log('res', res);
    res && formData.value.menuId
      ? await useSysMenuApi.update(formData.value as SysMenuItem)
      : await useSysMenuApi.add(formData.value);
  } catch (error) {
    /** */
    console.error('Error', error);
  }
  emits('refresh');
};
const handleCancel = () => {
  console.log('取消');
  emits('refresh');
};
const emits = defineEmits(['refresh']);

const originTree = ref<SysMenuItem[]>([]);
const getTree = async () => {
  const res = await useSysMenuApi.tree();
  originTree.value = res.data;
};
onMounted(() => {
  getTree();
});
defineExpose({
  init,
});
</script>
<style lang="scss"></style>
